package user_service

import (
	"github.com/lib/pq"
	"zhanyan/models"
	"zhanyan/pac/util"
	"zhanyan/service/classroom_service"
	"zhanyan/service/seat_service"
)

type User struct {
	ID           int            `json:"id";gorm:"primary_key"`
	Username     string         `json:"username,omitempty"`
	Password     string         `json:"password,omitempty"`
	Name         string         `json:"name,omitempty"`
	SchoolCode   string         `json:"school_code,omitempty"`
	Introduction string         `json:"introduction,omitempty"`
	Power        int            `json:"power,omitempty"`                                 // 如果是教师就为1，如果是学生就为0
	ChatNames    pq.StringArray `json:"chat_names,omitempty" gorm:"type:varchar(255)[]"` // 用户所在聊天室的名字列表
}

type Teacher struct {
	User
	TeacherCode string `json:"teacher_code,omitempty"`
	Phone       string `json:"phone,omitempty"`
	Classroom   []classroom_service.Classroom
}

type Student struct {
	User
	StudentCode string `json:"student_code,omitempty"`
	Seat        seat_service.Seat
}

func (s *Student) Add() error {
	if s.IsExist() {
		return util.UserHasError
	}
	student := &models.Student{}
	err := util.Transfer(s, student)
	if err != nil {
		return err
	}
	s.ID, err = models.AddStudent(student)
	if err != nil {
		return err
	}
	return nil
}

func (t *Teacher) Add() error {
	if t.IsExist() {
		return util.UserHasError
	}
	teacher := &models.Teacher{}
	err := util.Transfer(t, teacher)
	if err != nil {
		return err
	}
	t.ID, err = models.AddTeacher(teacher)
	if err != nil {
		return err
	}
	return nil
}

// IsExist 用户是否存在
func (u User) IsExist() bool {
	b, _ := models.CheckUser(u.Username, u.Password)
	return b
}

// IsExistById 同过id判断教师是否存在
func (t *Teacher) IsExistById() bool {
	b, _ := models.CheckTeacherById(t.ID)
	return b
}

// IsExistById 同过id判断学生是否存在
func (s *Student) IsExistById() bool {
	b, _ := models.CheckStudentById(s.ID)
	return b
}

func (t *Teacher) Update() error {
	if !t.IsExistById() {
		return util.UserNotExistError
	}

	teacher := &models.Teacher{}
	err := util.Transfer(t, teacher)
	if err != nil {
		return err
	}
	return models.UpdateTeacher(teacher)
}

func (s *Student) Update() error {
	if !s.IsExistById() {
		return util.UserNotExistError
	}

	student := &models.Student{}
	err := util.Transfer(s, student)
	if err != nil {
		return err
	}
	return models.UpdateStudent(student)
}

func (t *Teacher) Delete() error {
	if !t.IsExistById() {
		return util.UserNotExistError
	}
	return models.DeleteTeacher(t.ID)
}

func (t *Teacher) DeleteInClass(cid int) error {
	if !t.IsExistById() {
		return util.UserNotExistError
	}
	return models.DeleteTeacherInClass(t.ID, cid)
}

func (t *Teacher) DeleteAllClass() error {
	if !t.IsExistById() {
		return util.UserNotExistError
	}
	return models.DeleteTeacherInAllClass(t.ID)
}

func (s *Student) Delete() error {
	if !s.IsExistById() {
		return util.UserNotExistError
	}
	return models.DeleteStudent(s.ID)
}

func (u *User) GetByName() error {
	student, err := models.CheckStudentByName(u.Username)
	if err == nil && student != nil {
		// 获取学生聊天室内容
		s, err := models.QueryStudentById(student.ID)
		if err != nil {
			return err
		}
		if s.Seat.ClassroomID != 0 {
			classroom, err := models.QueryClassroom(s.Seat.ClassroomID)
			if err != nil {
				if err != nil {
					return err
				}
			}
			chatName := []string{}
			chatName = append(chatName, classroom.Name)
			student.ChatNames = chatName
		}
		err = util.Transfer(&(student.User), u)
		if err != nil {
			return err
		}
		return nil
	}
	teacher, err := models.CheckTeacherByName(u.Username)
	if err == nil && teacher != nil {
		// 获取老师聊天室内容
		classrooms, err := models.QueryClassroomByTid(teacher.ID)
		if err != nil {
			return err
		}
		chatNames := []string{}
		for _, classroom := range *classrooms {
			chatNames = append(chatNames, classroom.Name)
		}
		teacher.ChatNames = chatNames
		err = util.Transfer(&(teacher.User), u)
		if err != nil {
			return err
		}
		return nil
	}
	return err
}

func (s *Student) Get() error {
	if !s.IsExistById() {
		return util.UserNotExistError
	}
	student, err := models.QueryStudentById(s.ID)
	if err != nil {
		return err
	}
	err = util.Transfer(student, s)
	if err != nil {
		return err
	}
	return nil
}

func (t *Teacher) Get() error {
	if !t.IsExistById() {
		return util.UserNotExistError
	}
	teacher, err := models.QueryTeacherById(t.ID)
	if err != nil {
		return err
	}
	err = util.Transfer(teacher, t)
	if err != nil {
		return err
	}
	return nil
}

func (t *Teacher) GetInClass() error {
	if !t.IsExistById() {
		return util.UserNotExistError
	}
	teacher, err := models.QueryTeacherById(t.ID)
	if err != nil {
		return err
	}
	classrooms, err := models.QueryClassroomByTid(t.ID)
	teacher.Classroom = *classrooms
	err = util.Transfer(teacher, t)
	if err != nil {
		return err
	}
	if err != nil {
		return err
	}
	return nil
}

func (s *Student) GetAll() (*[]Student, error) {
	students, err := models.QueryStudents()
	if err != nil {
		return nil, err
	}
	ss := &[]Student{}
	for _, student := range *students {
		err = util.Transfer(&student, s)
		if err != nil {
			return nil, err
		}
		*ss = append(*ss, *s)
	}

	return ss, nil
}

func (t *Teacher) GetAll() (*[]Teacher, error) {
	teacher, err := models.QueryTeachers()
	if err != nil {
		return nil, err
	}
	ts := &[]Teacher{}
	for _, student := range *teacher {
		err = util.Transfer(&student, t)
		if err != nil {
			return nil, err
		}
		*ts = append(*ts, *t)
	}

	return ts, nil
}

func (t *Teacher) GetPage(pageSize, pageCode int) (*[]Teacher, error) {
	pageCode--
	teacher, err := models.QueryTeachersPage(pageSize, pageCode)
	if err != nil {
		return nil, err
	}
	ts := &[]Teacher{}
	for _, student := range *teacher {
		err = util.Transfer(&student, t)
		if err != nil {
			return nil, err
		}
		*ts = append(*ts, *t)
	}

	return ts, nil
}

func (s *Student) GetPage(pageSize, pageCode int) (*[]Student, error) {
	pageCode--
	students, err := models.QueryStudentsPage(pageSize, pageCode)
	if err != nil {
		return nil, err
	}
	ss := &[]Student{}
	for _, student := range *students {
		err = util.Transfer(&student, s)
		if err != nil {
			return nil, err
		}
		*ss = append(*ss, *s)
	}

	return ss, nil
}
